package com.zhouwr.common.utils;

/**
 * @program: jeecg-boot-iotcp
 * @description: 三维向量
 * @author: zhouwr
 * @create: 2020-11-03 13:50
 * @version：1.0
 **/

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 三维向量类 处理空间向量问题 提供平面求垂直向量 向量旋转 向量求膜 向量转单位向量等函数
 * Created by ssochi on 11/25 0025.
 */

@Data
@Slf4j
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@NoArgsConstructor
public class Vector3 {
    double x;
    double y;
    double z;

    public Vector3(JSONObject obj) {
        if (obj == null) {
            obj = new JSONObject();
            obj.put("x", 0d);
            obj.put("y", 0d);
            obj.put("z", 0d);
        }
        this.x = obj.getDouble("x");
        this.y = obj.getDouble("y");
        this.z = obj.getDouble("z");
    }

    public Vector3(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public Vector3(String vstr) {
        log.info(vstr);
        try {
            final String[] vs = vstr.split(",");
            this.x = Double.parseDouble(vs[0]);
            this.y = Double.parseDouble(vs[1]);
            this.z = Double.parseDouble(vs[2]);
        } catch (Exception e) {
            throw new RuntimeException("3维向量数值转换错误！");
        }

    }

    /**
     * 获得方向相同膜为r的向量
     *
     * @param v
     * @param r
     * @return
     */
    public static Vector3 getmR(Vector3 v, double r) {
        double x = v.x;
        double y = v.y;
        double z = v.z;
        double sum = x * x + y * y + z * z;
        double k = Math.sqrt(sum / (r * r));
        x = x / k;
        y = y / k;
        z = z / k;
        return new Vector3(x, y, z);
    }

    /**
     * 获得两个点的距离
     *
     * @param in1
     * @param in2
     * @return distance
     */
    public static double getDistance(Vector3 in1, Vector3 in2) {
        double distance = Math.sqrt(Math.pow((in1.x - in2.x), 2) + Math.pow((in1.y - in2.y), 2) + Math.pow((in1.z - in2.z), 2));
        return distance;
    }

    /**
     * 求与v1,v2向量垂直的向量 r是返回向量的膜
     *
     * @param v1
     * @param v2
     * @param r
     * @return
     */
    public static Vector3 getvertical(Vector3 v1, Vector3 v2, Double r) {
        Double ax = v1.x;
        Double ay = v1.y;
        Double az = v1.z;
        Double bx = v2.x;
        Double by = v2.y;
        Double bz = v2.z;
        double x = ay * bz - az * by;
        double y = az * bx - ax * bz;
        double z = ax * by - ay * bx;
        Vector3 target = new Vector3(x, y, z);
        target = Vector3.getmR(target, r);
        return target;
    }

    /**
     * 向量求膜
     *
     * @param v
     * @return
     */
    public static double getmodulus(Vector3 v) {
        return Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2) + Math.pow(v.z, 2));
    }

    /**
     * 向量求和
     *
     * @param in
     * @return
     */
    public Vector3 add(Vector3 in) {
        return new Vector3(x + in.x, y + in.y, z + in.z);
    }

    /**
     * 向量求和
     *
     * @param in1
     * @param in2
     * @return
     */
    public Vector3 add(Vector3 in1, Vector3 in2) {
        double x = in1.x + in2.x;
        double y = in1.y + in2.y;
        double z = in1.z + in2.z;
        return new Vector3(x, y, z);
    }

    /**
     * 向量求差
     *
     * @param in
     * @return
     */
    public Vector3 sub(Vector3 in) {
        return new Vector3(x - in.x, y - in.y, z - in.z);
    }

    /**
     * 向量求差
     *
     * @param in1
     * @param in2
     * @return
     */
    public Vector3 sub(Vector3 in1, Vector3 in2) {
        double x = in1.x - in2.x;
        double y = in1.y - in2.y;
        double z = in1.z - in2.z;
        return new Vector3(x, y, z);
    }


    @Override
    public String toString() {
        return x+","+y+","+z;
    }
}

